package util;

import Implementaciones.Cola;
import Implementaciones.Conjunto;
import Implementaciones.Vector;
import TDA.ColaTDA;
import TDA.ConjuntoTDA;
import TDA.VectorTDA;

public class OperacionesTDA<T> {

	public ConjuntoTDA<T> clonar(ConjuntoTDA<T> origen) {
		ConjuntoTDA<T> clon = new Conjunto<T>();
		clon.inicializarConjunto();
		ConjuntoTDA<T> aux = new Conjunto<T>();
		aux.inicializarConjunto();

		while (!origen.conjuntoVacio()) {
			T elemento = origen.elegir();
			origen.sacar(elemento);
			clon.agregar(elemento);
			aux.agregar(elemento);
		}

		while (!aux.conjuntoVacio()) {
			T elemento = aux.elegir();
			aux.sacar(elemento);
			origen.agregar(elemento);
		}

		return clon;
	}
	
	public int longitud(ConjuntoTDA<T> conjunto) {
		ConjuntoTDA<T> aux = new Conjunto<T>();
		aux.inicializarConjunto();
		int ax = 0;
		
		while(!conjunto.conjuntoVacio()) {
			T elemento = conjunto.elegir();
			conjunto.sacar(elemento);
			aux.agregar(elemento);
			ax++;
		}
		
		while(!aux.conjuntoVacio()) {
			T elemento = aux.elegir();
			aux.sacar(elemento);
			conjunto.agregar(elemento);
		}
		
		return ax;
	}
	
	public int longitud(ColaTDA<T> cola) {
		ColaTDA<T> aux = new Cola<T>();
		aux.inicializarCola();
		int ax = 0;
		
		while (!cola.colaVacia()) {
			T elemento = cola.primero();
			cola.desacolar();
			aux.acolar(elemento);
			ax++;
		}
		
		while (!aux.colaVacia()) {
			T elemento = aux.primero();
			cola.acolar(elemento);
			aux.desacolar();
		}

		return ax;
	}

	public void vaciar(ConjuntoTDA<T> conj) {		
		while (!conj.conjuntoVacio()) {
			T coord = conj.elegir();
			conj.sacar(coord);
		}		
	}
	
	public void agregarElementos(ConjuntoTDA<T> origen, ConjuntoTDA<T> destino) {		
		ConjuntoTDA<T> aux = new Conjunto<T>();
		aux.inicializarConjunto();
		
		while (!origen.conjuntoVacio()) {
			T elemento = origen.elegir();
			origen.sacar(elemento);
			destino.agregar(elemento);
			aux.agregar(elemento);
		}
		
		while (!aux.conjuntoVacio()) {
			T elemento = aux.elegir();
			aux.sacar(elemento);
			origen.agregar(elemento);
		}
	}
	
	public void reemplazarElementos(ConjuntoTDA<T> origen, ConjuntoTDA<T> destino) {
		vaciar(destino);
		agregarElementos(origen, destino);
	}
	
	public void agregarElementos(ColaTDA<T> origen, ColaTDA<T> destino) {		
		ColaTDA<T> aux = new Cola<T>();
		aux.inicializarCola();
		
		while (!origen.colaVacia()) {
			T elemento = origen.primero();
			origen.desacolar();
			aux.acolar(elemento);
			destino.acolar(elemento);
		}
		
		while (!aux.colaVacia()) {
			T elemento = aux.primero();
			aux.desacolar();
			origen.acolar(elemento);
		}		
	}
	
	public void remover(ColaTDA<T> cola, T t) {	
		ColaTDA<T> aux = new Cola<T>();
		aux.inicializarCola();
		
		while (!cola.colaVacia()) {
			T elemento = cola.primero();
			cola.desacolar();
			if (!elemento.equals(t)) {
				aux.acolar(elemento);
			}
		}
		
		while (!aux.colaVacia()) {
			T elemento = aux.primero();
			aux.desacolar();
			cola.acolar(elemento);
		}
	}
	
	public void vaciar(ColaTDA<T> cola) {		
		while (!cola.colaVacia()) {
			cola.desacolar();
		}		
	}
	
	public void reemplazarElementos(ColaTDA<T> origen, ColaTDA<T> destino) {
		vaciar(destino);
		agregarElementos(origen, destino);
	}
	
	public ColaTDA<T> clonar(ColaTDA<T> cola) {
		ColaTDA<T> clon = new Cola<T>();
		clon.inicializarCola();
		ColaTDA<T> aux = new Cola<T>();
		aux.inicializarCola();
		
		while (!cola.colaVacia()) {
			T elemento = cola.primero();		
			cola.desacolar();
			aux.acolar(elemento);
			clon.acolar(elemento);	
		}
		
		while (!aux.colaVacia()) {
			T elemento = aux.primero();
			aux.desacolar();
			cola.acolar(elemento);
		}
		
		return clon;
	}
	
	public boolean pertenece(ColaTDA<T> cola, T t) {
		boolean pertenece = false;
		ColaTDA<T> aux = new Cola<T>();
		aux.inicializarCola();
		
		T elem = null;
		while (!cola.colaVacia()) {
			elem = cola.primero();
			cola.desacolar();
			if (elem.equals(t)) {
				pertenece = true;
			}
			aux.acolar(elem);
		}

		while (!aux.colaVacia()) {
			T elemento = aux.primero();
			aux.desacolar();
			cola.acolar(elemento);
		}
		
		return pertenece;
	}
	
	public T obtenerUltimoElemento(ColaTDA<T> cola) {		
		ColaTDA<T> aux = new Cola<T>();
		aux.inicializarCola();
		
		T elem = null;		
		while (!cola.colaVacia()) {
			elem = cola.primero();
			cola.desacolar();
			aux.acolar(elem);
		}
		
		while (!aux.colaVacia()) {
			T elemento = aux.primero();
			aux.desacolar();
			cola.acolar(elemento);
		}

		return elem;
	}
	
	public VectorTDA<T> conjuntoAVector(ConjuntoTDA<T> conjunto) throws Exception {
		VectorTDA<T> vector = new Vector<T>();
		vector.inicializarVector(longitud(conjunto));
		int pos = 0;
		
		while(!conjunto.conjuntoVacio()) {
			T elemento = conjunto.elegir();
			conjunto.sacar(elemento);
			vector.agregarElemento(pos++, elemento);
		}
		
		for(int i = 0; i < pos; i++) {
			conjunto.agregar(vector.recuperarElemento(i));
		}
		
		return vector;
	}
}
